/*
     Copyright 2007 Joseph M. Ferner

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.IO;

namespace OpenServers.Net.Common.FileSystem.Disk {
    /// <summary>
    /// file system object backed by disk.
    /// </summary>
    /// <typeparam name="T">A type of <see cref="FileSystemInfo"/>.</typeparam>
    public abstract class DiskFileSystemObject<T> : IFileSystemObject where T : FileSystemInfo {
        private readonly T _fileSystemInfo;
        private readonly IDirectory _parent;

        /// <summary>
        /// constructor.
        /// </summary>
        /// <param name="parent">The parent directory.</param>
        /// <param name="fileSystemInfo">The file system info for the object to wrap.</param>
        public DiskFileSystemObject(IDirectory parent, T fileSystemInfo) {
            _parent = parent;
            _fileSystemInfo = fileSystemInfo;
        }

        /// <summary>
        /// The name of the object.
        /// </summary>
        public virtual string Name {
            get {
                if (Parent == null) { // handle root directory case.
                    return "/";
                }
                return _fileSystemInfo.Name;
            }
        }

        /// <summary>
        /// The last modified date.
        /// </summary>
        public DateTime LastModified {
            get { return _fileSystemInfo.LastWriteTime; }
        }

        /// <summary>
        /// Deletes the object.
        /// </summary>
        public void Delete() {
            _fileSystemInfo.Delete();
        }

        /// <summary>
        /// The wrapped file system info.
        /// </summary>
        public T FileSystemInfo {
            get { return _fileSystemInfo; }
        }

        /// <summary>
        /// flag whether the object exists.
        /// </summary>
        public bool Exists {
            get { return FileSystemInfo.Exists; }
        }

        /// <summary>
        /// The parent object.
        /// </summary>
        public IDirectory Parent {
            get { return _parent; }
        }

        /// <summary>
        /// flag marking this object as read only.
        /// </summary>
        public bool ReadOnly {
            get { return (FileSystemInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly; }
        }

        /// <summary>
        /// moves the object to another location.
        /// </summary>
        /// <param name="fso"></param>
        public abstract void MoveTo(IFileSystemObject fso);

        /// <summary>
        /// Gets the full path of this object.
        /// </summary>
        public string FullPath {
            get { return FileSystemUtils.GetFullPath(this); }
        }
    }
}
